from django.shortcuts import render, get_object_or_404
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action, api_view
from rest_framework.permissions import IsAuthenticated, AllowAny
from .models import ParsedQuestion, ParserTask
from .serializers import ParsedQuestionSerializer, ParserTaskSerializer, DocumentMinimalSerializer
from .document_parsers import get_parser_for_document, detect_answer, parse_multiple_choice_question, parse_multiple_questions
from .format_converter import FormatConverter
from django.utils import timezone
import logging

# 尝试导入Document模型，如果不存在则记录警告
try:
    from documents.models import Document
except ImportError:
    logger = logging.getLogger(__name__)
    logger.warning("无法导入Document模型，某些功能可能不可用")
    Document = None

# 尝试导入Exercise相关模型，如果不存在则记录警告
try:
    from exercises.models import ExerciseSet, Exercise
    from exercises.serializers import ExerciseSetDetailSerializer
except ImportError:
    logger = logging.getLogger(__name__)
    logger.warning("无法导入Exercise相关模型，导入练习功能可能不可用")
    ExerciseSet = None
    Exercise = None
    ExerciseSetDetailSerializer = None

logger = logging.getLogger(__name__)

# 添加格式转换器API端点
@api_view(['POST'])
def convert_format_endpoint(request):
    """使用格式转换器解析文档"""
    try:
        document_id = request.data.get('document_id')
        format_type = request.data.get('format_type', '4')  # 默认自动识别格式
        
        if not document_id:
            return Response(
                {'success': False, 'message': '未提供文档ID'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 获取文档
        try:
            document = Document.objects.get(id=document_id)
        except Document.DoesNotExist:
            return Response(
                {'success': False, 'message': '文档不存在'},
                status=status.HTTP_404_NOT_FOUND
            )
        
        # 创建解析任务
        task = ParserTask.objects.create(
            document=document,
            status='pending',
            auto_detect_answers=True
        )
        
        # 创建格式转换器
        converter = FormatConverter(document=document, task=task)
        
        # 处理文档
        success, result = converter.process_document(format_type=format_type)
        
        if success:
            return Response({
                'success': True,
                'message': '文档解析成功',
                'task_id': task.id,
                'result': result
            })
        else:
            return Response({
                'success': False,
                'message': '文档解析失败',
                'task_id': task.id,
                'error': result.get('error', '未知错误')
            }, status=status.HTTP_400_BAD_REQUEST)
            
    except Exception as e:
        logger.error(f"格式转换器解析文档时出错: {str(e)}")
        return Response(
            {'success': False, 'message': f'处理出错: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

# 添加直接解析文本的API端点
@api_view(['POST'])
def parse_text_endpoint(request):
    """直接解析文本中的题目，不需要文档"""
    try:
        text = request.data.get('text')
        
        if not text:
            return Response(
                {'success': False, 'message': '未提供文本内容'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        logger.info(f"开始解析文本，长度: {len(text)}")
        
        # 尝试解析多个题目
        parsed_questions = parse_multiple_questions(text)
        
        if parsed_questions:
            logger.info(f"成功解析出{len(parsed_questions)}个题目")
            
            # 返回所有解析出的题目
            return Response({
                'success': True,
                'message': f'成功解析出{len(parsed_questions)}个题目',
                'question': parsed_questions[0] if parsed_questions else None,
                'all_questions': parsed_questions,
                'question_count': len(parsed_questions)
            })
        
        # 如果没有解析出多个题目，尝试解析单个题目
        parsed = parse_multiple_choice_question(text)
        
        if not parsed:
            logger.warning("无法解析题目")
            return Response(
                {'success': False, 'message': '无法解析题目，请检查文本格式是否正确'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        logger.info("成功解析单个题目")
        return Response({
            'success': True,
            'message': '成功解析题目',
            'question': parsed,
            'all_questions': [parsed],
            'question_count': 1
        })
        
    except Exception as e:
        logger.error(f"解析文本错误: {str(e)}")
        return Response(
            {'success': False, 'message': f'解析文本失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

class ParsedQuestionViewSet(viewsets.ModelViewSet):
    """解析后的题目视图集"""
    queryset = ParsedQuestion.objects.all()
    serializer_class = ParsedQuestionSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """允许按文档ID筛选题目，并根据auto_detect_answers参数决定是否检测答案"""
        queryset = ParsedQuestion.objects.all()
        document_id = self.request.query_params.get('document_id')
        auto_detect = self.request.query_params.get('auto_detect_answers', 'true').lower() == 'true'
        
        if document_id:
            queryset = queryset.filter(document_id=document_id)
            
            # 如果启用了自动检测答案，检查每个题目是否已有检测结果
            if auto_detect:
                for question in queryset:
                    if not question.detected_answer:
                        question.detected_answer = detect_answer(question.content)
                        question.save()
                        
                        # 如果检测到答案且原题目没有答案，则设置答案
                        if question.detected_answer and not question.answer:
                            question.answer = f'选项{question.detected_answer}'
                            question.save()
        
        return queryset
    
    @action(detail=False, methods=['post'])
    def import_to_exercises(self, request):
        """将解析后的题目导入到练习题系统中"""
        document_id = request.data.get('document_id')
        title = request.data.get('title')
        description = request.data.get('description', '')
        is_public = request.data.get('is_public', False)
        
        if not document_id:
            return Response(
                {'error': '未提供文档ID'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        if not title:
            return Response(
                {'error': '未提供练习集标题'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # 导入exercises应用的模型和视图
            from exercises.models import ExerciseSet, Exercise
            from exercises.serializers import ExerciseSetDetailSerializer
            from django.db import transaction
            
            # 获取文档
            document = get_object_or_404(Document, pk=document_id)
            
            # 获取文档中的题目
            questions = ParsedQuestion.objects.filter(document=document)
            
            if not questions.exists():
                return Response(
                    {'error': '该文档没有解析出题目'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 创建练习集和练习题
            with transaction.atomic():
                # 创建练习集
                exercise_set = ExerciseSet.objects.create(
                    title=title,
                    description=description,
                    created_by=request.user,
                    is_public=is_public
                )
                
                # 创建练习题
                exercises = []
                for question in questions:
                    exercise = Exercise(
                        exercise_set=exercise_set,
                        content=question.content,
                        answer=question.answer,
                        question_type=question.question_type,
                        source_question=question
                    )
                    exercises.append(exercise)
                
                # 批量创建练习题
                Exercise.objects.bulk_create(exercises)
                
                # 返回创建的练习集
                serializer = ExerciseSetDetailSerializer(exercise_set)
                return Response(
                    {
                        'success': True,
                        'message': f'成功从文档导入{len(exercises)}个题目到练习集',
                        'exercise_set': serializer.data
                    },
                    status=status.HTTP_201_CREATED
                )
                
        except Exception as e:
            logger.error(f"导入题目到练习集错误: {str(e)}")
            return Response(
                {'success': False, 'message': f'导入题目到练习集失败: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

class ParserTaskViewSet(viewsets.ModelViewSet):
    """解析任务视图集"""
    queryset = ParserTask.objects.all()
    serializer_class = ParserTaskSerializer
    permission_classes = [IsAuthenticated]
    
    def get_permissions(self):
        """允许任何人查看任务状态，但只有认证用户可以创建或修改任务"""
        if self.action in ['retrieve', 'list']:
            permission_classes = [AllowAny]
        else:
            permission_classes = [IsAuthenticated]
        return [permission() for permission in permission_classes]
    
    def get_queryset(self):
        """允许按文档ID筛选任务"""
        queryset = ParserTask.objects.all().order_by('-created_at')
        document_id = self.request.query_params.get('document_id')
        if document_id:
            queryset = queryset.filter(document_id=document_id)
        return queryset
    
    @action(detail=False, methods=['post'])
    def parse_document(self, request):
        """创建一个解析任务并开始解析文档"""
        try:
            document_id = request.data.get('document_id')
            auto_detect_answers = request.data.get('auto_detect_answers', True)
            
            if not document_id:
                return Response(
                    {'success': False, 'message': '未提供文档ID'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 获取文档
            document = get_object_or_404(Document, pk=document_id)
            
            # 创建解析任务
            task = ParserTask.objects.create(
                document=document,
                status='processing',  # 直接设置为处理中
                auto_detect_answers=auto_detect_answers
            )
            
            # 获取适合该文档的解析器
            try:
                parser = get_parser_for_document(document, task)
            except ValueError as e:
                task.status = 'failed'
                task.error_message = str(e)
                task.save()
                return Response(
                    {'success': False, 'message': str(e)},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 解析文档
            parser.parse()
            
            # 保存解析结果
            questions = parser.save_questions()
            
            # 更新任务状态
            task.status = 'completed'
            task.questions_count = len(questions)
            task.completed_at = timezone.now()
            task.save()
            
            return Response(
                {
                    'success': True,
                    'message': f'成功创建解析任务并提取{len(questions)}个题目',
                    'task_id': task.id,
                    'questions_count': len(questions)
                },
                status=status.HTTP_201_CREATED
            )
            
        except Exception as e:
            logger.error(f"创建解析任务错误: {str(e)}")
            # 如果任务已创建，更新状态为失败
            if 'task' in locals():
                task.status = 'failed'
                task.error_message = str(e)
                task.save()
            return Response(
                {'success': False, 'message': f'创建解析任务失败: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=True, methods=['get'])
    def questions(self, request, pk=None):
        """获取指定任务解析出的题目"""
        task = self.get_object()
        questions = ParsedQuestion.objects.filter(document=task.document)
        serializer = ParsedQuestionSerializer(questions, many=True)
        return Response(serializer.data)
    
    @action(detail=False, methods=['post'])
    def detect_answers(self, request):
        """为指定文档的题目检测答案"""
        try:
            document_id = request.data.get('document_id')
            auto_detect = request.data.get('auto_detect', True)
            
            if not document_id:
                return Response(
                    {'success': False, 'message': '未提供文档ID'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 获取文档
            document = get_object_or_404(Document, pk=document_id)
            
            # 获取该文档的所有题目
            questions = ParsedQuestion.objects.filter(document=document)
            updated_count = 0
            
            for question in questions:
                if auto_detect:
                    # 检测答案
                    detected = detect_answer(question.content)
                    question.detected_answer = detected
                    
                    # 如果检测到答案且原题目没有答案，则设置答案
                    if detected and not question.answer:
                        question.answer = f'选项{detected}'
                        updated_count += 1
                else:
                    # 清除检测结果
                    question.detected_answer = None
                
                question.save()
            
            # 更新任务的自动检测设置
            tasks = ParserTask.objects.filter(document=document)
            for task in tasks:
                task.auto_detect_answers = auto_detect
                task.save()
            
            return Response({
                'success': True,
                'message': f'已{auto_detect and "启用" or "禁用"}自动答案检测，更新了{updated_count}个题目',
                'updated_count': updated_count
            })
            
        except Exception as e:
            logger.error(f"检测答案错误: {str(e)}")
            return Response(
                {'success': False, 'message': f'检测答案失败: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

# 添加文档特定的解析端点
@api_view(['POST'])
def parse_document_endpoint(request, document_id):
    """文档解析端点，与前端DocumentParser.vue组件对应"""
    try:
        auto_detect_answers = request.data.get('auto_detect_answers', True)
        
        # 获取文档
        document = get_object_or_404(Document, pk=document_id)
        
        # 记录解析前的题目数量
        before_count = ParsedQuestion.objects.filter(document=document).count()
        logger.info(f"解析前题目数量: {before_count}, 文档ID: {document_id}")
        
        # 创建解析任务
        task = ParserTask.objects.create(
            document=document,
            status='processing',
            auto_detect_answers=auto_detect_answers
        )
        
        # 获取适合该文档的解析器
        try:
            parser = get_parser_for_document(document, task)
            logger.info(f"使用解析器: {parser.__class__.__name__}")
        except ValueError as e:
            task.status = 'failed'
            task.error_message = str(e)
            task.save()
            logger.error(f"获取解析器失败: {str(e)}")
            return Response(
                {'success': False, 'message': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 解析文档
        logger.info(f"开始解析文档: {document.title}")
        parser.parse()
        
        # 保存解析结果
        logger.info(f"开始保存解析结果")
        questions = parser.save_questions()
        
        # 记录解析后的题目数量
        after_count = ParsedQuestion.objects.filter(document=document).count()
        logger.info(f"解析后题目数量: {after_count}, 解析器返回题目数量: {len(questions)}")
        
        # 更新任务状态
        task.status = 'completed'
        task.questions_count = len(questions)
        task.completed_at = timezone.now()
        task.save()
        
        return Response({
            'success': True,
            'message': f'成功解析文档并提取{len(questions)}个题目',
            'questions_count': len(questions)
        })
        
    except Exception as e:
        logger.error(f"解析文档错误: {str(e)}")
        # 如果任务已创建，更新状态为失败
        if 'task' in locals():
            task.status = 'failed'
            task.error_message = str(e)
            task.save()
        return Response(
            {'success': False, 'message': f'解析文档失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

# 添加获取文档题目的端点
@api_view(['GET'])
def document_questions_endpoint(request, document_id):
    """获取指定文档的所有题目"""
    try:
        document = get_object_or_404(Document, pk=document_id)
        questions = ParsedQuestion.objects.filter(document=document)
        serializer = ParsedQuestionSerializer(questions, many=True)
        
        # 确保返回的是数组，而不是对象
        return Response(serializer.data)
    except Exception as e:
        logger.error(f"获取文档题目错误: {str(e)}")
        return Response(
            {'success': False, 'message': f'获取文档题目失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

# 添加导入练习的端点
@api_view(['POST'])
def import_exercises_endpoint(request):
    """将文档题目导入到练习系统，与前端DocumentParser.vue组件对应"""
    try:
        document_id = request.data.get('document_id')
        title = request.data.get('title')
        description = request.data.get('description', '')
        is_public = request.data.get('is_public', False)
        
        if not document_id:
            return Response(
                {'success': False, 'message': '未提供文档ID'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        if not title:
            return Response(
                {'success': False, 'message': '未提供练习集标题'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 检查是否可以导入
        if not all([ExerciseSet, Exercise, ExerciseSetDetailSerializer]):
            return Response(
                {'success': False, 'message': '导入练习功能不可用，缺少必要的模块'},
                status=status.HTTP_501_NOT_IMPLEMENTED
            )
        
        # 获取文档
        document = get_object_or_404(Document, pk=document_id)
        
        # 获取文档中的题目
        questions = ParsedQuestion.objects.filter(document=document)
        
        if not questions.exists():
            return Response(
                {'success': False, 'message': '该文档没有解析出题目'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 创建练习集和练习题
        from django.db import transaction
        with transaction.atomic():
            # 创建练习集
            exercise_set = ExerciseSet.objects.create(
                title=title,
                description=description,
                created_by=request.user,
                is_public=is_public
            )
            
            # 创建练习题
            exercises = []
            for question in questions:
                exercise = Exercise(
                    exercise_set=exercise_set,
                    content=question.content,
                    answer=question.answer,
                    question_type=question.question_type,
                    source_question=question
                )
                exercises.append(exercise)
            
            # 批量创建练习题
            Exercise.objects.bulk_create(exercises)
            
            # 返回创建的练习集
            serializer = ExerciseSetDetailSerializer(exercise_set)
            return Response(
                {
                    'success': True,
                    'message': f'成功从文档导入{len(exercises)}个题目到练习集',
                    'exercise_set': serializer.data
                },
                status=status.HTTP_201_CREATED
            )
            
    except Exception as e:
        logger.error(f"导入题目到练习集错误: {str(e)}")
        return Response(
            {'success': False, 'message': f'导入题目到练习集失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

# 添加共享文档端点
@api_view(['GET'])
def shared_documents_endpoint(request):
    """获取共享文档列表，与前端SharedDocuments.vue组件对应"""
    try:
        # 检查Document模型是否可用
        if Document is None:
            return Response(
                {'success': False, 'message': '文档功能不可用'},
                status=status.HTTP_501_NOT_IMPLEMENTED
            )
        
        # 获取共享文档
        # 假设Document模型有is_shared字段，如果没有，需要根据实际模型调整查询条件
        shared_documents = Document.objects.filter(is_shared=True)
        
        # 序列化文档
        serializer = DocumentMinimalSerializer(shared_documents, many=True)
        
        return Response({
            'success': True,
            'count': shared_documents.count(),
            'results': serializer.data
        })
        
    except Exception as e:
        logger.error(f"获取共享文档错误: {str(e)}")
        return Response(
            {'success': False, 'message': f'获取共享文档失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

# 添加获取单个共享文档的端点
@api_view(['GET'])
def shared_document_detail_endpoint(request, document_id):
    """获取单个共享文档的详细信息"""
    try:
        # 检查Document模型是否可用
        if Document is None:
            return Response(
                {'success': False, 'message': '文档功能不可用'},
                status=status.HTTP_501_NOT_IMPLEMENTED
            )
        
        # 获取共享文档
        try:
            document = Document.objects.get(pk=document_id, is_shared=True)
        except Document.DoesNotExist:
            return Response(
                {'success': False, 'message': '共享文档不存在或未共享'},
                status=status.HTTP_404_NOT_FOUND
            )
        
        # 序列化文档
        serializer = DocumentMinimalSerializer(document)
        
        # 获取文档相关的解析任务
        tasks = ParserTask.objects.filter(document=document).order_by('-created_at')
        task_serializer = ParserTaskSerializer(tasks, many=True)
        
        # 获取文档相关的题目数量
        questions_count = ParsedQuestion.objects.filter(document=document).count()
        
        return Response({
            'success': True,
            'document': serializer.data,
            'tasks': task_serializer.data,
            'questions_count': questions_count
        })
        
    except Exception as e:
        logger.error(f"获取共享文档详情错误: {str(e)}")
        return Response(
            {'success': False, 'message': f'获取共享文档详情失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

# 添加重新解析文档的端点
@api_view(['POST'])
def reparse_document_endpoint(request, document_id):
    """重新解析已解析过的文档，与前端DocumentParser.vue组件对应"""
    try:
        auto_detect_answers = request.data.get('auto_detect_answers', True)
        
        # 获取文档
        document = get_object_or_404(Document, pk=document_id)
        
        # 创建新的解析任务
        task = ParserTask.objects.create(
            document=document,
            status='processing',
            auto_detect_answers=auto_detect_answers
        )
        
        # 删除该文档之前解析的题目
        ParsedQuestion.objects.filter(document=document).delete()
        
        # 获取适合该文档的解析器
        try:
            parser = get_parser_for_document(document, task)
        except ValueError as e:
            task.status = 'failed'
            task.error_message = str(e)
            task.save()
            return Response(
                {'success': False, 'message': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 解析文档
        parser.parse()
        
        # 保存解析结果
        questions = parser.save_questions()
        
        # 更新任务状态
        task.status = 'completed'
        task.questions_count = len(questions)
        task.completed_at = timezone.now()
        task.save()
        
        return Response({
            'success': True,
            'message': f'成功重新解析文档并提取{len(questions)}个题目',
            'questions_count': len(questions)
        })
        
    except Exception as e:
        logger.error(f"重新解析文档错误: {str(e)}")
        # 如果任务已创建，更新状态为失败
        if 'task' in locals():
            task.status = 'failed'
            task.error_message = str(e)
            task.save()
        return Response(
            {'success': False, 'message': f'重新解析文档失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )
